﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace TozCombat
{
    class Personnage
    {
        protected static int nbPlayers = 0; // S'incrémente a chaque instanciation de Personnage
        protected String name;
        protected Vector2 position;
        protected int vitesse = 4;
        protected GraphicsDeviceManager graphics;
        protected bool inTheAir, isPunching, isFaceHit, isKO, isBlocking, isKicking = false;
        protected double vi, t = 0;
        protected double g = 2000;
        protected Boolean isRight;
        protected Personnage adversaire;
        private AnimationPlayer animationPlayer;

        public AnimationPlayer AnimationPlayer
        {
            get { return animationPlayer; }
            set { animationPlayer = value; }
        }
        protected Animation animationStand;
        protected Animation animationWalk;
        protected Animation animationJump;
        protected Animation animationPunch;
        protected Animation animationKick;
        protected Animation animationFaceHit;
        protected Animation animationKO;
        protected Animation animationBlock;
        protected Rectangle collision;
        protected Texture2D lifeMeter;
        protected Rectangle lifeRect;
        protected int floorPosition = 0;
        protected int playerNum;
        protected Manette manette;
        protected bool canPunch, kickOne = true;
        protected bool canKick = false;
        protected Color playerColor;
        private bool canMove = false;
        protected int degatsPoing = 20;
        protected int degatsPied = 30;
        public static int totalLife = 200;
        private int life = totalLife;//full meter

        public bool CanMove
        {
            get { return canMove; }
            set { canMove = value; }
        }
        public String Name
        {
            get { return name; }
            set { name = value; }
        }
        public Rectangle LifeRect
        {
            get { return lifeRect; }
            set { lifeRect = value; }
        }
        public int Life
        {
            get { return life; }
            set { life = value; }
        }
        public Personnage Adversaire
        {
            get { return adversaire; }
            set { adversaire = value; }
        }
        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }
        public Boolean IsRight
        {
            get { return isRight; }
            set { isRight = value; }
        }
        public GraphicsDeviceManager Graphics
        {
            get { return graphics; }
            set { graphics = value; }
        }
        public Rectangle Collision
        {
            get { return collision; }
            set { collision = value; }
        }
        public bool IsKO
        {
            get { return isKO; }
            set { isKO = value; }
        }

        public Personnage(String name)
        {
            this.name = name;
            playerNum = ++nbPlayers;
            manette = new Manette();
        }

        public virtual void Initialize(SpriteBatch batch)
        {
            if (playerNum == 1)
            {
                manette.initController1();
                playerColor = Color.White;
            }
            else
            {
                manette.initController2();
                playerColor = Color.Violet;
            }
            lifeRect = new Rectangle(560, 30, 200, 20);
        }

        public void LoadContent(ContentManager content)
        {
            animationStand = new Animation(content.Load<Texture2D>("sprites/Ryu/stand"), 50, 0.1f, true);
            animationWalk = new Animation(content.Load<Texture2D>("sprites/Ryu/walk"), 66, 0.1f, true);
            animationJump = new Animation(content.Load<Texture2D>("sprites/Ryu/jump"), 60, 0.2f, false);
            animationPunch = new Animation(content.Load<Texture2D>("sprites/Ryu/punch"), 80, 0.2f, false);
            animationKick = new Animation(content.Load<Texture2D>("sprites/Ryu/kick"), 70, 0.15f, false);
            animationFaceHit = new Animation(content.Load<Texture2D>("sprites/Ryu/facehit"), 70, 0.15f, false);
            animationKO = new Animation(content.Load<Texture2D>("sprites/Ryu/ko"), 80, 0.15f, false);
            animationBlock = new Animation(content.Load<Texture2D>("sprites/Ryu/block"), 43, 0.15f, true);
            // On démarre l'animation par défaut
            animationPlayer.PlayAnimation(animationStand);
            lifeMeter = content.Load<Texture2D>("meter");
        }

        public void Draw(SpriteBatch batch, GameTime gameTime)
        {
            batch.Draw(lifeMeter, lifeRect, Color.White);
            if (isRight)
            {
                animationPlayer.Draw(gameTime, batch, position, SpriteEffects.FlipHorizontally, playerColor);
            }
            else
            {
                animationPlayer.Draw(gameTime, batch, position, SpriteEffects.None, playerColor);
            }
        }

        public virtual void Update(GameTime gameTime)
        {
            if (canMove == true)
            {
                KeyboardState kbState = Keyboard.GetState();
                if (Keyboard.GetState().IsKeyUp(manette.Poing)){
                    canPunch = true;
                }
                if (Keyboard.GetState().IsKeyUp(manette.Pied)){
                    canKick = true;
                }

                if (Keyboard.GetState().IsKeyDown(manette.Poing) && manette.Hashtable[manette.Poing].Equals(true) && canPunch == true) 
                {
                    canPunch = false;
                    isPunching = true;
                    manette.behaviorHit();
                }
                else if (Keyboard.GetState().IsKeyDown(manette.Pied) && manette.Hashtable[manette.Pied].Equals(true) && canKick == true)
                {
                    canKick = false;
                    isKicking = true;
                    manette.behaviorHit();
                }
                else if (kbState.IsKeyDown(manette.Droite)  && manette.Hashtable[manette.Droite].Equals(true))
                {
                    if (!inTheAir)
                        animationPlayer.PlayAnimation(animationWalk);
                    if (position.X + Collision.Width + vitesse >= adversaire.Position.X + adversaire.Collision.Width / 2 &&
                        position.X + Collision.Width + vitesse <= adversaire.Position.X + adversaire.Collision.Width && position.Y == 640)
                    {
                        if (adversaire.Position.X + adversaire.Collision.Width <= graphics.GraphicsDevice.Viewport.Width)
                        {
                            changeXEnnemy(adversaire.Position.X + 1);
                        }
                    }
                    else if (position.X + Collision.Width + vitesse <= graphics.GraphicsDevice.Viewport.Width)
                    {
                        position.X += vitesse;
                    }
                }
                else if (kbState.IsKeyDown(manette.Gauche) && manette.Hashtable[manette.Gauche].Equals(true))
                {
                    if (!inTheAir)
                        animationPlayer.PlayAnimation(animationWalk);
                    if (position.X - Collision.Width - vitesse <= adversaire.Position.X - adversaire.Collision.Width / 2 &&
                        position.X - Collision.Width - vitesse >= adversaire.Position.X - adversaire.Collision.Width && position.Y == 640)
                    {
                        if (adversaire.Position.X - adversaire.Collision.Width >= 0)
                        {
                            changeXEnnemy(adversaire.Position.X - 1);
                        }
                    }
                    else if (position.X - Collision.Width - vitesse >= 0)
                    {
                        position.X -= vitesse;
                    }
                }
                else
                {
                    // Aucune touche n'est pressée, on ne fait rien
                    if (!inTheAir  && !isPunching && !isKicking  && !isFaceHit && !isBlocking)
                    {
                        animationPlayer.PlayAnimation(animationStand);
                    }
                }

                if (Keyboard.GetState().IsKeyDown(manette.Haut) && manette.Hashtable[manette.Haut].Equals(true))
                {
                    inTheAir = true;
                    manette.behaviorJump();
                    vi = -Collision.Height * 8.5; 
                }

                if (Keyboard.GetState().IsKeyDown(manette.Bas) && manette.Hashtable[manette.Bas].Equals(true))
                {
                    isBlocking = true;
                    manette.behaviorBlock();
                }

                /*
                ************************************************************************
                * gestion du saut 
                ************************************************************************
                */
                if (inTheAir)
                {
                    animationPlayer.PlayAnimation(animationJump);
                    position.Y = (float)(vi * t + g * t * t / 2) + graphics.GraphicsDevice.Viewport.Height - Collision.Height - floorPosition;
                    t = t + gameTime.ElapsedGameTime.TotalSeconds; 
                }

                if (Position.Y > graphics.GraphicsDevice.Viewport.Height - Collision.Height - floorPosition)
                {
                    position.Y = graphics.GraphicsDevice.Viewport.Height - Collision.Height - floorPosition;
                    inTheAir = false;
                    manette.behaviorMove();
                    t = 0;
                }

                /*
                ************************************************************************
                * gestion du coup de poing 
                ************************************************************************
                */
                if (isPunching)
                {
                    animationPlayer.PlayAnimation(animationPunch);
                    if ((isRight == false && position.X + (collision.Width + 20) >= (Adversaire.position.X - Adversaire.Collision.Width / 2))
                       || (isRight == true && position.X - (collision.Width + 20) <= (Adversaire.position.X + Adversaire.Collision.Width / 2))
                        )
                    {
                        if (!Adversaire.isBlocking && position.Y - (collision.Height) <= Adversaire.position.Y)
                        {
                            if (animationPlayer.isHitFace() && kickOne)
                            {
                                Adversaire.isFaceHit = true;
                                Adversaire.lostLife(degatsPoing);
                                Adversaire.manette.behaviorHit();
                                kickOne = false;
                            }
                        }
                    }

                    if (!animationPlayer.isMoving())
                    {
                        isPunching = false;
                        kickOne = true;
                        Adversaire.manette.behaviorMove();
                        manette.behaviorMove();
                    }

                }

                /*
                ************************************************************************
                * gestion du coup de pied 
                ************************************************************************
                */
                if (isKicking)
                {
                    animationPlayer.PlayAnimation(animationKick);
                    if ((isRight == false && position.X + (collision.Width + 20) >= (Adversaire.position.X - Adversaire.Collision.Width / 2))
                       || (isRight == true && position.X - (collision.Width + 20) <= (Adversaire.position.X + Adversaire.Collision.Width / 2)))
                    {
                        if (!Adversaire.isBlocking)
                        {
                            if (animationPlayer.isHitFace() && kickOne && position.Y - (collision.Height) <= Adversaire.position.Y)
                            {
                                Adversaire.isFaceHit = true;
                                Adversaire.lostLife(degatsPied);
                                Adversaire.manette.behaviorHit();
                                kickOne = false;
                            }
                        }
                    }
                    
                    if (!animationPlayer.isMoving())
                    { 
                        isKicking = false;
                        kickOne = true;
                        Adversaire.manette.behaviorMove();
                        manette.behaviorMove();
                    }
                    
                }

                /*
                ************************************************************************
                * gestion de la collision 
                ************************************************************************
                */
                if (isFaceHit)
                {
                    animationPlayer.PlayAnimation(animationFaceHit);
                    if (!animationPlayer.isMoving())
                    {
                        isFaceHit = false;
                        manette.behaviorMove();
                    }
                }

               /*
                ************************************************************************
                * gestion du blocage
                ************************************************************************
                */
                if (isBlocking)
                {
                    animationPlayer.PlayAnimation(animationBlock);
                    if (Keyboard.GetState().IsKeyUp(manette.Bas))
                    {
                        isBlocking = false;
                        manette.behaviorMove();
                    }
                }
                
                /*
                 ************************************************************************
                 * gestion du KO
                 ************************************************************************
                 */
                if (isKO)
                {
                    animationPlayer.PlayAnimation(animationKO);
                    manette.behaviorHit();
                }
            }
        }

        public void changeXEnnemy(float x)
        {
            adversaire.position.X = x;
        }

        public void lostLife(int number)
        {
            if (playerNum == 1)
            {
                if (lifeRect.Width > 0)
                {
                    lifeRect.Width -= number;
                }
            }
            else
            {
                if (lifeRect.Width > 0)
                {
                    lifeRect.Width -= number;
                    LifeRect = new Rectangle(LifeRect.X + number, 30, LifeRect.Width, 20);
                }
            }

            // Quand on frappe l'adversaire
            this.Life -= number;
            if (this.Life <= 0)
            {
                isKO = true;
            }
        }

        public void initPosition()
        {
            isKO = false;
            if (playerNum == 1)
            {
                this.position = new Vector2(Collision.Width, (graphics.GraphicsDevice.Viewport.Height - Collision.Height - floorPosition));
                LifeRect = new Rectangle(60, 30, 200, 20);
            }
            else
            {
                this.position = new Vector2((graphics.GraphicsDevice.Viewport.Width - Collision.Width), (graphics.GraphicsDevice.Viewport.Height - Collision.Height - floorPosition));
                LifeRect = new Rectangle(760, 30, 200, 20);
            }

            this.Life = totalLife;
            this.CanMove = true;

        }
    }
}